<template>
  <div>
    <!-- 三级分类全局组件 -->
    <Category :scenes="scenes"></Category>
    <el-card style="margin: 10px 0px">
      <div v-show="scenes == 0">
        <el-button
          type="primary"
          size="default"
          icon="Plus"
          :disabled="categoryStore.c3CategorySelectId ? false : true"
          @click="addAttr"
        >
          添加属性
        </el-button>
        <el-table border style="margin: 10px 0px" :data="attrArr">
          <el-table-column label="序号" align="center" type="index" width="80px"></el-table-column>
          <el-table-column label="属性名称" prop="attrName" width="120px"></el-table-column>
          <el-table-column label="属性值名称">
            <template #="{ row }">
              <el-tag style="margin: 5px" v-for="(item, $index) in row.attrValueList" :key="item.id" effect="light" :type="$index%2==0?'warning':'success'">
                {{ item.valueName }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="170px">
            <template #="{ row }">
              <!-- row：已有属性的对象 -->
              <el-button type="primary" size="small" icon="Edit" @click="updateAttr(row)">编辑</el-button>
              <el-popconfirm @confirm="deleteAttr(row.id)" width="200px" :title="`你确认要删除${row.attrName}吗?`">
                <template #reference>
                  <el-button type="danger" size="small" icon="Delete">删除</el-button>
                </template>
              </el-popconfirm>
              
            </template>
          </el-table-column>
        </el-table>
      </div>

      <!-- 添加属性与修改数据的结构 -->
      <div v-show="scenes == 1">
        <el-form :inline="true">
          <el-form-item label="属性名称">
            <el-input :ref="(vc: any)=> inputAttrTitle = vc" placeholder="请您输入属性的名称" v-model="attrParams.attrName"></el-input>
          </el-form-item>
        </el-form>
        <el-button :disabled="attrParams.attrName.trim() ? false : true" type="primary" size="default" icon="Plus" @click="addAttrValue">添加属性值</el-button>
        <el-button size="default" @click="cancal">取消</el-button>
        <el-table border style="margin: 10px 0px" :data="attrParams.attrValueList">
          <el-table-column label="序号" type="index" align="center" width="80px"></el-table-column>
          <el-table-column label="属性值">
            <template #="{ row, $index }">
              <el-input :ref="(vc: any)=> inputAttr[$index] = vc" v-if="row.flag" @blur="toView($index,row)" size="small" v-model="row.valueName">{{ row.valueName }}</el-input>
              <div v-else @click="toEdit($index, row)">{{ row.valueName }}</div>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="170">
            <template #="{ $index}">
              <el-button type="danger" size="small" @click="attrParams.attrValueList.splice($index, 1)">删除</el-button> 
            </template>
          </el-table-column>
        </el-table>
        <el-button type="primary" size="default" @click="save" :disabled="attrParams.attrValueList.length>0?false:true">保存</el-button>
        <el-button size="default" @click="cancal">取消</el-button>
      </div>
    </el-card>
  </div>
</template>
<script setup lang="ts">
import { watch, ref, reactive, nextTick, onBeforeUnmount } from 'vue'
// 获取分类的仓库
import useCategoryStore from '@/store/modules/category'
// 引入获取已有属性与属性值的接口
import { reqAttrInfoList } from '@/api/product/attr'
// 引入ts类型
import type { AttrResponseData, attrList, Attr, AttrValue } from '@/api/product/attr/type'
import { ElMessage } from 'element-plus/lib/components/index.js'
import { reqAddOrUpdateAttr, reqDeleteAttr } from '@/api/product/attr/index'

let categoryStore = useCategoryStore()
// 存放三级分类已有的属性与属性值
let attrArr = ref<attrList[]>([])
// 定义card组件内容切换变量
let scenes = ref<number>(0) // scenes=0，正常显示table内容；scenes=1，显示添加或者修改属性的结构

// 准备一个变量来存储，添加修改结构中需要输入属性名称input实例对象，从而在用户点击"添加属性"用来获取input焦点
let inputAttrTitle = ref<any>()

// 准备一个数组：将来存储对应的组件el-input
let inputAttr = ref<any>([])

// 收集新增属性的数据
const attrParams = reactive<Attr>({
  attrName: '', // 新增属性的名字
  attrValueList: [
    // {
    //   valueName: "" // 值的名称
    // }
  ],
  categoryId: '', // 三级分类的ID
  categoryLevel: 3, // 代表的三级分类
})

// 监视三级分类菜单的选中的id是否有变化
watch(
  () => categoryStore.c3CategorySelectId,
  () => {
    // 清空上次查询的属性和属性值
    attrArr.value = []
    // 保证三级分类得有才能发请求
    if (!categoryStore.c3CategorySelectId) return
    // 获取分类的属性和属性值
    getAttr()
  },
)

// 获取已有的属性与属性值的方法
const getAttr = async () => {
  // 获取分类的id
  const { c1CategorySelectId, c2CategorySelectId, c3CategorySelectId } = categoryStore
  const result: AttrResponseData = await reqAttrInfoList(
    c1CategorySelectId,
    c2CategorySelectId,
    c3CategorySelectId,
  )
  if (result.code == 200) {
    attrArr.value = result.data
  } else {
    ElMessage({
      type: 'error',
      message: `获取属性的值失败: ${result.message}`,
    })
  }
}

// 添加属性按钮的回调
const addAttr = () => {
  // 每次添加之前，先清空之前添加的数据并收集三级分类的id
  Object.assign(attrParams, {
    attrName: '', // 新增属性的名字
    attrValueList: [],
    categoryId: categoryStore.c3CategorySelectId, // 三级分类的ID
    categoryLevel: 3, // 代表的三级分类
    id: ''
  })
  // 切换为添加与修改属性的结构
  scenes.value = 1
  // 每次添加时进行进行搜集了三级分类的id，这里无需再次收集
  // attrParams.categoryId = categoryStore.c3CategorySelectId
  // 获取input焦点
  nextTick(()=>{
    inputAttrTitle.value.focus()
  })
}
// 修改属性按钮的回调
const updateAttr = (row: Attr) => {
  // 切换为添加与修改属性的结构
  scenes.value = 1
  // 把row对象的内容合并给attrParms，注意这里需要使用深拷贝
  //  JSON.parse(JSON.stringify(row))为深拷贝；否则就为浅拷贝，会出现诡异的问题
  // Object.assign(attrParams, JSON.parse(JSON.stringify(row)))
  Object.assign(attrParams, row)
}
// 取消按钮的回调
const cancal = () => {
  scenes.value = 0
}

// 添加属性值的回调函数
const addAttrValue = () => {
  // 点击添加属性值按钮的时候，向数组添加一个属性值对象
  attrParams.attrValueList.push({
    valueName: '',
    flag: true // 用来控制属性值是编辑模式还是查看模式
  })
  // 获取最后一个el-input组件进行聚焦
  nextTick(()=>{
    inputAttr.value[attrParams.attrValueList.length - 1].focus()
  })
}

// 删除已有的删除
const deleteAttr = async (attrId: number) => {
  let result = await reqDeleteAttr(attrId)
  if(result.code == 200){
    ElMessage({
      type: 'success',
      message: '删除属性成功'
    })
    // 重新获取全部已有属性 
    getAttr()
  } else {
    ElMessage({
      type: 'error',
      message: '删除属性失败'
    })
  }

}


// 保存用户添加的属性值
const save = async () => {
  let result = await reqAddOrUpdateAttr(attrParams)
  if (result.code == 200) {
    // 添加成功后，scenes切换为正常table的结构
    scenes.value = 0
    // 提示信息
    ElMessage({
      type: 'success',
      message: attrParams.id ? '修改成功' : '添加成功', // 有id说明是修改，没有id说明为新添加
    })
    // 再次请求，获取全部已有的属性和属性值
    getAttr()
  } else {
    ElMessage({
      type: 'error',
      message: attrParams.id ? '修改失败' : '添加失败',
    })
  }
}

// 查看模式的回调函数
const toView = ($index: number, row: AttrValue) => {
  // 1. 非法情况1的判断(如果用户什么都没有输入就变为div，当用户再次点击的时候就无法再变为input模式了
  if(row.valueName.trim()==''){
    // 提示信息
    ElMessage({
      type: 'error',
      message: '属性值不能为空'
    })
    // 删除调用对应属性值为空的元素
    attrParams.attrValueList.splice($index, 1)
    return
  }
  // 2. 非法情况2的判断，用户输入的属性值不能相同
  let repeat = attrParams.attrValueList.find((item)=>{
    // 切记把当前失去焦点的属性值对象从当前数组排除
    if(item!=row){
      return item.valueName == row.valueName
    }
  })
  // 如果有重复的，后面的语句禁止执行
  if(repeat) {
    // 提示信息
    ElMessage({
      type: 'error',
      message: '属性值不能重复'
    })
    // 删除调用对应属性值为空的元素
    attrParams.attrValueList.splice($index, 1)
    return
  }
  // 相应的属性值对象flag：变为false，展示div
  row.flag = false
}

// 编辑模式的回调函数
const toEdit = ($index: number,row: AttrValue) => {
  // 相应的属性值对象flag：变为true，展示input
  row.flag = true
  nextTick(()=>{
    inputAttr.value[$index].focus()
  })
}

// 当路由组件销毁的时候，把仓库当中的分类相关的数据清空
onBeforeUnmount(()=>{
  categoryStore.$reset()
})
</script>

<script lang="ts">
export default {
  name: 'ProductAttr',
}
</script>
<style scoped></style>
